﻿#include "VAOneXMLAdaptorSpectra.h"
#include "rapidxml.hpp"
#include "FITKAcousticsPhysics/FITKAcousticsPhysics.h"
#include "FITKAcousticsPhysics/FITKAcousticsAbstractSpectra.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsSpectraManager.h"
#include "FITKAcousticsPhysics/FITKSpectraModalDensity.h"
#include "FITKAcousticsPhysics/FITKSpectraDampingLossFactor.h"
#include "FITKAcousticsPhysics/FITKSpectraCouplingLossFactor.h"
#include "FITKAcousticsPhysics/FITKSpectraAbsorptionCoefficient.h"
#include "FITKAcousticsPhysics/FITKSpectraWavenumber.h"
#include "FITKAcousticsPhysics/FITKAcousticsAbstractSpectra.h"
#include "FITKAcousticsPhysics/FITKSpectraTransmissionLoss.h"
#include "FITKAcousticsPhysics/FITKSpectraInsertionLoss.h"
#include "FITKAcousticsPhysics/FITKSpectraAcceleration.h"
#include "FITKAcousticsPhysics/FITKSpectraAngularVelocity.h"
#include "FITKAcousticsPhysics/FITKSpectraEnergy.h"
#include "FITKAcousticsPhysics/FITKSpectraForce.h"
#include "FITKAcousticsPhysics/FITKSpectraMoment.h"
#include "FITKAcousticsPhysics/FITKSpectraPressure.h"
#include "FITKAcousticsPhysics/FITKSpectraVelocity.h"
#include "FITKAcousticsPhysics/FITKSpectraPower.h"
#include "FITKAcousticsPhysics/FITKSpectraAcceleration.h"
#include "FITKAcousticsPhysics/FITKSpectraShearModulus.h"
#include <iostream>
#include <QDebug>
#include <QMessageBox>

namespace IO
{
    bool VAOneXMLAdaptorSpectra::adaptR()
    {
        // 指针判断是否为空
        if(!_node)
        {
            return false;
        }

        if(!_dataObj)
        {
            return false;
        }

        // 读取频谱
        // 返回操作是否成功
        return readRealSpectrum();
    }

    bool VAOneXMLAdaptorSpectra::adaptW()
    {
        // 指针判断是否为空
        if(!_node)
        {
            return false;
        }

        if(!_dataObj)
        {
            return false;
        }

        // 返回操作是否成功
        return writeRealSpectrum();
    }

    bool VAOneXMLAdaptorSpectra::readRealSpectrum()
    {
        // 获取声谱管理类
        auto spectraDataManager = dynamic_cast<Acoustics::FITKAcousticsSpectraManager*>(_dataObj);
        // 获取RealSpectrum节点
        rapidxml::xml_node<char>* realSpectrumNode = _node->first_node("RealSpectrum");
        if (!realSpectrumNode) return false;

        // 循环处理每个RealSpectrum节点
        while (realSpectrumNode)
        {
            bool b = false;
            // 获取名称节点
            auto nameNode = realSpectrumNode->first_node("Name")->first_node();
            QString strName;

            // 检查名称节点是否存在
            if (nameNode != nullptr)
            {
                // 读取名称值
                strName = readStrNodeValue(nameNode, &b);
            }

            // 读取谱类型
            int spectrumType = readStrAttribute(realSpectrumNode, "spectrum_type", &b).toInt();
             // 查找已有谱数据
            Acoustics::FITKAcousticsAbstractSpectra* spectra {};
            auto m = spectraDataManager->getDataByName(strName);

            if(!m)
            {
                spectra = getSpectraByType(spectrumType);// 根据谱类型获取谱实例

                if(!spectra)
                {
                    // 处理下一个节点
                    realSpectrumNode = realSpectrumNode->next_sibling("RealSpectrum");
                    continue;
                }

                spectraDataManager->appendDataObj(spectra);// 添加谱对象到管理器

                if(b)
                {
                    spectra->setDataObjectName(strName);
                }
            }
            else
            {
                spectra = dynamic_cast<Acoustics::FITKAcousticsAbstractSpectra*>(m);
            }

            auto noteNode = realSpectrumNode->first_node("Note");// 获取备注节点

            if (noteNode != nullptr)
            {
                // 读取备注值
                QString strNote = readStrNodeValue(noteNode, &b);

                if (b)
                {
                    spectra->setNotes(strNote);
                }
            }

            auto dimensionsNode = realSpectrumNode->first_node("Dimensions");
            if (dimensionsNode)
            {
                double dimL = readDoubleAttribute(dimensionsNode, "dimL", &b);
                //if (b) spectra->setDimensionL(dimL);
                double dimM = readDoubleAttribute(dimensionsNode, "dimM", &b);
                 //if (b) spectra->setDimensionM(dimM);
                double dimT = readDoubleAttribute(dimensionsNode, "dimT", &b);
                //if (b) spectra->setDimensionT(dimT);
            }

            // 读取频率信息
            auto frequencyDomainNode = realSpectrumNode->first_node("FrequencyDomain");

            // 检查频率节点是否存在
            if (frequencyDomainNode)
            {
                 // 读取类型
                int domainType = readDoubleAttribute(frequencyDomainNode, "domain_type", &b);
                //从VAOne类型转换成对应的DomainType
                if (domainType == 1)  //标准音频
                {
                    domainType = 1;
                }
                if (domainType == 2)  //标准1/3信频
                {
                    domainType = 2;
                }
                if (domainType == 4)  //1/n信频
                {
                    domainType = 3;
                }
                if (domainType == 0)  //固定带宽
                {
                    domainType = 4;
                }
                // 转换为枚举类型
                Acoustics::FITKGlobalFrequencyDomain::DomainType t = static_cast<Acoustics::FITKGlobalFrequencyDomain::DomainType>(domainType);
                 // 读取起始频率
                double startFreq = readDoubleAttribute(frequencyDomainNode, "start_freq", &b);
                // 读取结束频率
                double endFreq = readDoubleAttribute(frequencyDomainNode, "end_freq", &b);
                if (t == 1 || t == 2)  //标准音频和标准1/3信频
                {
                    spectra->init(startFreq, endFreq, t);
                }
                if (t == 3)  //1/n信频
                {
                    //读取Octave数量
                    int octaveFreq = readDoubleAttribute(frequencyDomainNode, "proportion", &b);
                    spectra->init(startFreq, endFreq, t, octaveFreq);
                }
                if (t == 4)  //固定带宽
                {
                    //读取bandWidth带宽
                    double bandWidthFreq = readDoubleAttribute(frequencyDomainNode, "bandwidth_freq", &b);
                    spectra->init(startFreq, endFreq, t, bandWidthFreq);
                }
            }

            int index = 0;  //索引值

            for (auto realNode = realSpectrumNode->first_node("Real"); realNode; realNode = realNode->next_sibling("Real"), ++index)
            { 
                //读取实部值
                double r = readDoubleNodeValue(realNode, &b);
                // 设置值到频谱对象中
                spectra->setSpectraValueAt(index, r);
            }
            if (index != spectra->getSpectraCount())
            {
                this->consoleMessage(3,QString("Read spectra error:%1.").arg(strName));
            }

            // 处理下一个RealSpectrum节点
            realSpectrumNode = realSpectrumNode->next_sibling("RealSpectrum");
        }
        //读取成功
        return true;
    }

    bool VAOneXMLAdaptorSpectra::writeRealSpectrum()
    {
        // 定义有效的枚举值列表（不包括 None）
        using AcousticsSpectraType = Acoustics::FITKAcousticsAbstractSpectra::AcousticsSpectraType;
        QList<AcousticsSpectraType> validSpectraTypes =
        {
            AcousticsSpectraType::Force,
            AcousticsSpectraType::Moment,
            AcousticsSpectraType::Pressure,
            AcousticsSpectraType::Velocity,
            AcousticsSpectraType::Energy,
            AcousticsSpectraType::Damping,
            AcousticsSpectraType::TransmissionLoss,
            AcousticsSpectraType::InsertionLoss,
            AcousticsSpectraType::Absorption,
            AcousticsSpectraType::Coupling,
            AcousticsSpectraType::Power,
            AcousticsSpectraType::Acceleration,
            AcousticsSpectraType::AnlrVelocity,
            AcousticsSpectraType::Wavenumber,
            AcousticsSpectraType::ModalDensity,
            AcousticsSpectraType::ShearModulus
        };

        // 遍历有效枚举值
        bool b = true;
        for (auto type : validSpectraTypes)
            b &= writeRealSpectrumTemplate(type);

        return b;
    }

    bool VAOneXMLAdaptorSpectra::writeRealSpectrumTemplate(Acoustics::FITKAcousticsAbstractSpectra::AcousticsSpectraType t)
    {
        Acoustics::FITKAcousticsSpectraManager* spectraManager = dynamic_cast<Acoustics::FITKAcousticsSpectraManager*>(_dataObj);
        if(!spectraManager) return false;

        bool ok = true;

        QList<Acoustics::FITKAcousticsAbstractSpectra*> spectraDatas = spectraManager->getSpectraByType(t);
        for (const auto& spectraData : spectraDatas)
        {
            Acoustics::FITKAcousticsAbstractSpectra* data = dynamic_cast<Acoustics::FITKAcousticsAbstractSpectra*>(spectraData);
            if (!data) return false;

            // 创建RealSpectrum节点
            rapidxml::xml_node<char>* realSpectrumNode = createNodeElement(_node, "RealSpectrum");

            // 写入属性
            ok &= writeAttribute(realSpectrumNode, "spectrum_form", 0);
            //writeAttribute(realSpectrumNode, "spectrum_form", QString::number(data->getSpectraForm()));
            ok &= writeAttribute(realSpectrumNode, "spectrum_type", QString::number(t));

            // 创建名称和注释节点
            createNodeElement(realSpectrumNode, "Name", data->getDataObjectName());
            createNodeElement(realSpectrumNode, "Note", data->getNotes());

            // Dimensions
            rapidxml::xml_node<char>* dimensionsNode = createNodeElement(realSpectrumNode, "Dimensions");
            ok &= writeAttribute(dimensionsNode, "dimM", 0);
            ok &= writeAttribute(dimensionsNode, "dimL", 0);
            ok &= writeAttribute(dimensionsNode, "dimT", 0);
            /*writeAttribute(dimensionsNode, "dimL", data->getDimensionL());
            writeAttribute(dimensionsNode, "dimM", data->getDimensionM());
            writeAttribute(dimensionsNode, "dimT", data->getDimensionT());
            realSpectrumNode->append_node(dimensionsNode);*/

            // 写入频率
            rapidxml::xml_node<char>* frequencyDomainNode = createNodeElement(realSpectrumNode, "FrequencyDomain");
            ok &= writeAttribute(frequencyDomainNode, "start_freq", data->getStartFreq());
            ok &= writeAttribute(frequencyDomainNode, "end_freq", data->getEndFreq());
            ok &= writeAttribute(frequencyDomainNode, "domain_type", data->getDomainType());

            // 写入实部
            QList<Acoustics::SpectraValue> list = data->getSpectraValue();
            int count = list.size();
            for (int i = 0; i < count; i++)
                createNodeElement(realSpectrumNode, "Real", QString::number(list[i]._value.getReal()));
        }

        return true;
    }

    Acoustics::FITKAcousticsAbstractSpectra *VAOneXMLAdaptorSpectra::getSpectraByType(int type)
    {
        // 将传入的整型类型转换为频谱类型枚举
        Acoustics::FITKAcousticsAbstractSpectra::AcousticsSpectraType spectraType =
                static_cast<Acoustics::FITKAcousticsAbstractSpectra::AcousticsSpectraType>(type);

        switch (spectraType)
        {
            case Acoustics::FITKAcousticsAbstractSpectra::AcousticsSpectraType::Velocity:
                return new Acoustics::FITKSpectraVelocity;
            case Acoustics::FITKAcousticsAbstractSpectra::AcousticsSpectraType::Acceleration:
                 return new Acoustics::FITKSpectraAcceleration;
            case Acoustics::FITKAcousticsAbstractSpectra::AcousticsSpectraType::AnlrVelocity:
                return new Acoustics::FITKSpectraAngularVelocity;
            case Acoustics::FITKAcousticsAbstractSpectra::AcousticsSpectraType::Damping:
                return new Acoustics::FITKSpectraDampingLossFactor;
            case Acoustics::FITKAcousticsAbstractSpectra::AcousticsSpectraType::Absorption:
                 return new Acoustics::FITKSpectraAbsorptionCoefficient;
            case Acoustics::FITKAcousticsAbstractSpectra::AcousticsSpectraType::Coupling:
                return new Acoustics::FITKSpectraCouplingLossFactor;
            case Acoustics::FITKAcousticsAbstractSpectra::AcousticsSpectraType::Wavenumber:
                return new Acoustics::FITKSpectraWavenumber;
            case Acoustics::FITKAcousticsAbstractSpectra::AcousticsSpectraType::ModalDensity:
                 return new Acoustics::FITKSpectraModalDensity;
            case Acoustics::FITKAcousticsAbstractSpectra::AcousticsSpectraType::TransmissionLoss:
                return new Acoustics::FITKSpectraTransmissionLoss;
            case Acoustics::FITKAcousticsAbstractSpectra::AcousticsSpectraType::InsertionLoss:
                return new Acoustics::FITKSpectraInsertionLoss;
            case Acoustics::FITKAcousticsAbstractSpectra::AcousticsSpectraType::Force:
                return new Acoustics::FITKSpectraForce;
            case Acoustics::FITKAcousticsAbstractSpectra::AcousticsSpectraType::Moment:
                return new Acoustics::FITKSpectraMoment;
            case Acoustics::FITKAcousticsAbstractSpectra::AcousticsSpectraType::Pressure:
                return new Acoustics::FITKSpectraPressure;
            case Acoustics::FITKAcousticsAbstractSpectra::AcousticsSpectraType::Energy:
                return new Acoustics::FITKSpectraEnergy;
            case Acoustics::FITKAcousticsAbstractSpectra::AcousticsSpectraType::Power:
                return new Acoustics::FITKSpectraPower;
            case Acoustics::FITKAcousticsAbstractSpectra::AcousticsSpectraType::ShearModulus:
                return new Acoustics::FITKSpectraShearModulus;
            default:
                return nullptr;// 如果未匹配到任何类型，则返回空指针
        }
       // return nullptr;
    }
}
